﻿namespace Sage.Data.Extensions
{
    /// <summary>
    /// 提供长整型(long)类型的扩展方法，用于数值转换、格式化等常用操作。
    /// </summary>
    /// <remarks>
    /// 此类包含针对<see cref="long"/>类型的扩展方法，使长整型数值相关操作更加简洁和直观。
    /// 所有方法都是线程安全的，可以在多线程环境中使用。
    /// </remarks>
    public static class LongExtensions
    {
        #region 数值判断

        /// <summary>
        /// 判断数值是否在指定范围内（包含边界）。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <param name="min">最小值（包含）。</param>
        /// <param name="max">最大值（包含）。</param>
        /// <returns>如果数值在范围内则返回true，否则返回false。</returns>
        /// <example>
        /// <code>
        /// long score = 85;
        /// bool isPassing = score.Between(60, 100); // 返回 true
        /// bool isExcellent = score.Between(90, 100); // 返回 false
        /// 
        /// // 验证文件大小
        /// long fileSize = 1024 * 1024; // 1MB
        /// bool isValidSize = fileSize.Between(1024, 10 * 1024 * 1024); // 1KB到10MB
        /// </code>
        /// </example>
        public static bool Between(this long value, long min, long max)
        {
            return value >= min && value <= max;
        }

        /// <summary>
        /// 判断是否为偶数。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果是偶数则返回true，否则返回false。</returns>
        /// <example>
        /// <code>
        /// long number = 42;
        /// bool even = number.IsEven(); // 返回 true
        /// bool odd = number.IsOdd(); // 返回 false
        /// </code>
        /// </example>
        public static bool IsEven(this long value) => value % 2 == 0;

        /// <summary>
        /// 判断是否为奇数。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果是奇数则返回true，否则返回false。</returns>
        public static bool IsOdd(this long value) => value % 2 != 0;

        /// <summary>
        /// 判断数值是否为正数（大于0）。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果大于0则返回true。</returns>
        /// <example>
        /// <code>
        /// long balance = 1000;
        /// if (balance.IsPositive())
        /// {
        ///     Console.WriteLine("账户有余额");
        /// }
        /// </code>
        /// </example>
        public static bool IsPositive(this long value) => value > 0;

        /// <summary>
        /// 判断数值是否为负数（小于0）。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果小于0则返回true。</returns>
        public static bool IsNegative(this long value) => value < 0;

        /// <summary>
        /// 判断数值是否为0。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>如果等于0则返回true。</returns>
        public static bool IsZero(this long value) => value == 0;

        /// <summary>
        /// 获取数值的符号。
        /// </summary>
        /// <param name="value">要判断的数值。</param>
        /// <returns>正数返回1，负数返回-1，零返回0。</returns>
        /// <example>
        /// <code>
        /// long positive = 100;
        /// int sign1 = positive.GetSign(); // 返回 1
        /// 
        /// long negative = -50;
        /// int sign2 = negative.GetSign(); // 返回 -1
        /// 
        /// long zero = 0;
        /// int sign3 = zero.GetSign(); // 返回 0
        /// </code>
        /// </example>
        public static int GetSign(this long value)
        {
            return Math.Sign(value);
        }

        #endregion

        #region 格式化方法

        /// <summary>
        /// 将字节数格式化为易读可读的字符串（如 "1.5 MB"）。
        /// </summary>
        /// <param name="bytes">要格式化的字节数。</param>
        /// <param name="decimalPlaces">小数位数，默认为2位。</param>
        /// <returns>格式化后的字符串。</returns>
        /// <example>
        /// <code>
        /// long fileSize = 1536; 
        /// string size1 = fileSize.ToFileSizeString(); // 返回 "1.50 KB"
        /// string size2 = fileSize.ToFileSizeString(0); // 返回 "2 KB"
        /// 
        /// long largeSize = 1073741824; 
        /// string size3 = largeSize.ToFileSizeString(); // 返回 "1.00 GB"
        /// 
        /// long smallSize = 512;
        /// string size4 = smallSize.ToFileSizeString(); // 返回 "512 B"
        /// 
        /// long hugeSize = 1125899906842624; 
        /// string size5 = hugeSize.ToFileSizeString(); // 返回 "1.00 PB"
        /// </code>
        /// </example>
        /// <remarks>
        /// 使用1024作为进制基数（二进制标准），适用于文件大小、内存使用量等场景。
        /// 支持从字节(B)到拍字节(PB)的格式化。
        /// 当小数位数为0时，会对结果进行四舍五入。
        /// </remarks>
        public static string ToFileSizeString(this long bytes, int decimalPlaces = 2)
        {
            if (bytes == 0) return "0 B";

            string[] units = ["B", "KB", "MB", "GB", "TB", "PB"];

            int unitIndex = 0;
            double size = Math.Abs(bytes);

            while (size >= 1024 && unitIndex < units.Length - 1)
            {
                size /= 1024;
                unitIndex++;
            }

            // 如果是字节，不显示小数
            if (unitIndex == 0)
            {
                return $"{bytes} {units[unitIndex]}";
            }

            // 保持原始符号
            if (bytes < 0) size = -size;

            string format = $"F{Math.Max(0, decimalPlaces)}";
            return $"{size.ToString(format)} {units[unitIndex]}";
        }

        /// <summary>
        /// 将秒数转换为易读的时长字符串格式。
        /// </summary>
        /// <param name="seconds">总秒数。</param>
        /// <returns>
        /// 格式化的时长字符串，如"1小时30分45秒"、"2分30秒"、"45秒"等。
        /// </returns>
        /// <example>
        /// <code>
        /// long duration1 = 3661;
        /// string text1 = duration1.ToDurationString(); // 返回 "1小时1分1秒"
        /// 
        /// long duration2 = 150;
        /// string text2 = duration2.ToDurationString(); // 返回 "2分30秒"
        /// 
        /// long duration3 = 45;
        /// string text3 = duration3.ToDurationString(); // 返回 "45秒"
        /// 
        /// // 显示任务执行时间
        /// DateTime startTime = DateTime.Now;
        /// // ... 执行任务
        /// long elapsed = (long)(DateTime.Now - startTime).TotalSeconds;
        /// string message = $"任务完成，耗时：{elapsed.ToDurationString()}";
        /// 
        /// // 显示视频时长
        /// long videoSeconds = 3723; // 1小时2分3秒
        /// string videoDuration = videoSeconds.ToDurationString();
        /// </code>
        /// </example>
        /// <remarks>
        /// 自动选择合适的时间单位组合，不显示为0的单位。
        /// 支持秒、分钟、小时、天的组合显示。
        /// 常用于用户界面显示、日志记录、进度提示等场景。
        /// </remarks>
        public static string ToDurationString(this long seconds)
        {
            if (seconds < 0) return "0秒";

            var parts = new List<string>();

            if (seconds >= 86400) // 天
            {
                var days = seconds / 86400;
                parts.Add($"{days}天");
                seconds %= 86400;
            }

            if (seconds >= 3600) // 小时
            {
                var hours = seconds / 3600;
                parts.Add($"{hours}小时");
                seconds %= 3600;
            }

            if (seconds >= 60) // 分钟
            {
                var minutes = seconds / 60;
                parts.Add($"{minutes}分");
                seconds %= 60;
            }

            if (seconds > 0 || parts.Count == 0) // 秒
            {
                parts.Add($"{seconds}秒");
            }

            return string.Join("", parts);
        }

        /// <summary>
        /// 将数值格式化为带千分位分隔符的字符串。
        /// </summary>
        /// <param name="value">要格式化的数值。</param>
        /// <param name="separator">千分位分隔符，默认为逗号。</param>
        /// <returns>格式化后的字符串。</returns>
        /// <example>
        /// <code>
        /// long amount = 1234567890;
        /// string formatted = amount.ToThousandsSeparator(); // 返回 "1,234,567,890"
        /// string formatted2 = amount.ToThousandsSeparator(" "); // 返回 "1 234 567 890"
        /// 
        /// // 显示统计数据
        /// long userCount = 5234567;
        /// Console.WriteLine($"总用户数：{userCount.ToThousandsSeparator()}");
        /// </code>
        /// </example>
        public static string ToThousandsSeparator(this long value, string separator = ",")
        {
            return value.ToString($"#,0").Replace(",", separator);
        }

        /// <summary>
        /// 将数值转换为十六进制字符串。
        /// </summary>
        /// <param name="value">要转换的数值。</param>
        /// <param name="upperCase">是否使用大写字母，默认为true。</param>
        /// <returns>十六进制字符串。</returns>
        /// <example>
        /// <code>
        /// long color = 16711680; // 红色
        /// string hex = color.ToHex(); // 返回 "FF0000"
        /// string hex2 = color.ToHex(false); // 返回 "ff0000"
        /// 
        /// // 显示内存地址
        /// long address = 0x7FFFFFFFFFFF;
        /// string hexAddress = address.ToHex();
        /// </code>
        /// </example>
        public static string ToHex(this long value, bool upperCase = true)
        {
            return value.ToString(upperCase ? "X" : "x");
        }

        /// <summary>
        /// 将数值转换为二进制字符串。
        /// </summary>
        /// <param name="value">要转换的数值。</param>
        /// <returns>二进制字符串。</returns>
        /// <example>
        /// <code>
        /// long permissions = 7; // rwx
        /// string binary = permissions.ToBinary(); // 返回 "111"
        /// 
        /// long flags = 5; // 101
        /// string binaryFlags = flags.ToBinary();
        /// </code>
        /// </example>
        public static string ToBinary(this long value)
        {
            return Convert.ToString(value, 2);
        }

        /// <summary>
        /// 将分转换为货币格式的字符串（元）。
        /// </summary>
        /// <param name="cents">分为单位的金额。</param>
        /// <param name="currencySymbol">货币符号，默认为"¥"。</param>
        /// <returns>格式化的货币字符串。</returns>
        /// <example>
        /// <code>
        /// long cents = 12345; // 123.45元
        /// string price = cents.ToCurrency(); // 返回 "¥123.45"
        /// string usd = cents.ToCurrency("$"); // 返回 "$123.45"
        /// 
        /// // 显示商品价格
        /// long productPrice = 9999; // 99.99元
        /// Console.WriteLine($"价格：{productPrice.ToCurrency()}");
        /// </code>
        /// </example>
        public static string ToCurrency(this long cents, string currencySymbol = "¥")
        {
            decimal yuan = cents / 100m;
            return $"{currencySymbol}{yuan:F2}";
        }

        #endregion

        #region 类型转换

        /// <summary>
        /// 将长整型转换为整型，如果超出范围则抛出异常。
        /// </summary>
        /// <param name="value">要转换的长整型值。</param>
        /// <returns>转换后的整型值。</returns>
        /// <exception cref="OverflowException">当值超出int范围时抛出。</exception>
        /// <example>
        /// <code>
        /// long id = 12345L;
        /// int intId = id.ToInt(); // 返回 12345
        /// 
        /// long bigValue = long.MaxValue;
        /// int overflow = bigValue.ToInt(); // 抛出 OverflowException
        /// </code>
        /// </example>
        public static int ToInt(this long value)
        {
            return checked((int)value);
        }

        /// <summary>
        /// 将长整型安全转换为整型，超出范围返回null。
        /// </summary>
        /// <param name="value">要转换的长整型值。</param>
        /// <returns>转换成功返回整型值，超出范围返回null。</returns>
        /// <example>
        /// <code>
        /// long id = 12345L;
        /// int? intId = id.ToIntOrNull(); // 返回 12345
        /// 
        /// long bigValue = long.MaxValue;
        /// int? result = bigValue.ToIntOrNull(); // 返回 null
        /// 
        /// // 配合null合并运算符使用
        /// int finalId = bigValue.ToIntOrNull() ?? -1;
        /// </code>
        /// </example>
        public static int? ToIntOrNull(this long value)
        {
            if (value > int.MaxValue || value < int.MinValue)
                return null;
            return (int)value;
        }

        /// <summary>
        /// 将长整型安全转换为整型，超出范围返回默认值。
        /// </summary>
        /// <param name="value">要转换的长整型值。</param>
        /// <param name="defaultValue">超出范围时返回的默认值，默认为0。</param>
        /// <returns>转换后的整型值或默认值。</returns>
        /// <example>
        /// <code>
        /// long bigValue = long.MaxValue;
        /// int result = bigValue.ToIntOrDefault(-1); // 返回 -1
        /// </code>
        /// </example>
        public static int ToIntOrDefault(this long value, int defaultValue = 0)
        {
            return ToIntOrNull(value) ?? defaultValue;
        }

        /// <summary>
        /// 将长整型转换为双精度浮点数。
        /// </summary>
        /// <param name="value">要转换的长整型值。</param>
        /// <returns>转换后的双精度浮点数。</returns>
        /// <example>
        /// <code>
        /// long amount = 1000L;
        /// double percent = amount.ToDouble() / 100; // 计算百分比
        /// </code>
        /// </example>
        public static double ToDouble(this long value)
        {
            return value;
        }

        /// <summary>
        /// 将长整型转换为decimal类型，适用于精确的货币计算。
        /// </summary>
        /// <param name="value">要转换的长整型值。</param>
        /// <returns>转换后的decimal值。</returns>
        /// <example>
        /// <code>
        /// long cents = 12345L; // 分
        /// decimal yuan = cents.ToDecimal() / 100; // 转换为元
        /// </code>
        /// </example>
        public static decimal ToDecimal(this long value)
        {
            return value;
        }

        #endregion

        #region 时间转换

        /// <summary>
        /// 将Unix时间戳（秒）转换为DateTime。
        /// </summary>
        /// <param name="unixTimestamp">Unix时间戳（自1970年1月1日以来的秒数）。</param>
        /// <returns>对应的DateTime对象（UTC时间）。</returns>
        /// <example>
        /// <code>
        /// long timestamp = 1609459200; // 2021-01-01 00:00:00 UTC
        /// DateTime date = timestamp.FromUnixTimestamp(); 
        /// 
        /// // API返回的时间戳转换
        /// long apiTimestamp = 1638360000;
        /// DateTime createdAt = apiTimestamp.FromUnixTimestamp();
        /// DateTime localTime = createdAt.ToLocalTime(); // 转换为本地时间
        /// </code>
        /// </example>
        /// <remarks>
        /// 返回的是UTC时间，如需本地时间请使用ToLocalTime()方法转换。
        /// 适用于处理API时间戳、日志时间戳等场景。
        /// </remarks>
        public static DateTime FromUnixTimestamp(this long unixTimestamp)
        {
            return DateTimeOffset.FromUnixTimeSeconds(unixTimestamp).DateTime;
        }

        /// <summary>
        /// 将Unix时间戳（毫秒）转换为DateTime。
        /// </summary>
        /// <param name="unixTimestampMs">Unix时间戳（自1970年1月1日以来的毫秒数）。</param>
        /// <returns>对应的DateTime对象（UTC时间）。</returns>
        /// <example>
        /// <code>
        /// long timestampMs = 1609459200000; // 2021-01-01 00:00:00.000 UTC
        /// DateTime date = timestampMs.FromUnixTimestampMs();
        /// 
        /// // JavaScript时间戳转换
        /// long jsTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        /// DateTime date2 = jsTimestamp.FromUnixTimestampMs();
        /// </code>
        /// </example>
        public static DateTime FromUnixTimestampMs(this long unixTimestampMs)
        {
            return DateTimeOffset.FromUnixTimeMilliseconds(unixTimestampMs).DateTime;
        }

        /// <summary>
        /// 将长整型转换为TimeSpan（以毫秒为单位）。
        /// </summary>
        /// <param name="milliseconds">毫秒数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// long duration = 5000; // 5秒
        /// TimeSpan timeSpan = duration.ToTimeSpan();
        /// 
        /// // 设置延迟
        /// long delayMs = 1500;
        /// await Task.Delay(delayMs.ToTimeSpan());
        /// </code>
        /// </example>
        public static TimeSpan ToTimeSpan(this long milliseconds)
        {
            return TimeSpan.FromMilliseconds(milliseconds);
        }

        /// <summary>
        /// 将长整型秒数转换为TimeSpan对象。
        /// </summary>
        /// <param name="seconds">秒数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// long duration = 3661; // 1小时1分1秒
        /// TimeSpan timeSpan = duration.ToTimeSpanFromSeconds(); // 01:01:01
        /// 
        /// // API返回的持续时间
        /// long apiDuration = 7200; // 2小时
        /// TimeSpan taskDuration = apiDuration.ToTimeSpanFromSeconds();
        /// 
        /// // 缓存过期时间
        /// long cacheSeconds = 1800; // 30分钟
        /// TimeSpan cacheExpiry = cacheSeconds.ToTimeSpanFromSeconds();
        /// </code>
        /// </example>
        /// <remarks>
        /// 与现有的ToTimeSpan()方法（毫秒）形成区别，此方法处理秒级时间。
        /// 适用于Unix时间戳差值计算、API时间处理、配置时间转换等场景。
        /// </remarks>
        public static TimeSpan ToTimeSpanFromSeconds(this long seconds)
        {
            return TimeSpan.FromSeconds(seconds);
        }

        #endregion

        #region 时间快捷方法

        /// <summary>
        /// 将数值转换为指定天数的TimeSpan。
        /// </summary>
        /// <param name="value">天数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var expiry = DateTime.Now.Add(30L.Days()); // 30天后
        /// var cacheTime = 7L.Days(); // 7天的时间间隔
        /// </code>
        /// </example>
        public static TimeSpan Days(this long value) => TimeSpan.FromDays(value);

        /// <summary>
        /// 将数值转换为指定小时数的TimeSpan。
        /// </summary>
        /// <param name="value">小时数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var delay = 2L.Hours(); // 2小时
        /// var workTime = 8L.Hours(); // 8小时工作时间
        /// </code>
        /// </example>
        public static TimeSpan Hours(this long value) => TimeSpan.FromHours(value);

        /// <summary>
        /// 将数值转换为指定分钟数的TimeSpan。
        /// </summary>
        /// <param name="value">分钟数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var timeout = 30L.Minutes(); // 30分钟超时
        /// await Task.Delay(5L.Minutes()); // 延迟5分钟
        /// </code>
        /// </example>
        public static TimeSpan Minutes(this long value) => TimeSpan.FromMinutes(value);

        /// <summary>
        /// 将数值转换为指定秒数的TimeSpan。
        /// </summary>
        /// <param name="value">秒数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var delay = 10L.Seconds(); // 10秒
        /// </code>
        /// </example>
        public static TimeSpan Seconds(this long value) => TimeSpan.FromSeconds(value);

        /// <summary>
        /// 将数值转换为指定毫秒数的TimeSpan。
        /// </summary>
        /// <param name="value">毫秒数。</param>
        /// <returns>对应的TimeSpan对象。</returns>
        /// <example>
        /// <code>
        /// var delay = 500L.Milliseconds(); // 500毫秒
        /// </code>
        /// </example>
        public static TimeSpan Milliseconds(this long value) => TimeSpan.FromMilliseconds(value);

        #endregion

        #region 数值操作

        /// <summary>
        /// 确保数值在指定范围内，超出范围则返回边界值。
        /// </summary>
        /// <param name="value">要限制的数值。</param>
        /// <param name="min">最小值。</param>
        /// <param name="max">最大值。</param>
        /// <returns>限制在范围内的数值。</returns>
        /// <example>
        /// <code>
        /// long score = 150;
        /// long clampedScore = score.Clamp(0, 100); // 返回 100
        /// 
        /// long negativeValue = -10;
        /// long clampedValue = negativeValue.Clamp(0, 100); // 返回 0
        /// 
        /// long normalValue = 50;
        /// long clampedNormal = normalValue.Clamp(0, 100); // 返回 50
        /// </code>
        /// </example>
        public static long Clamp(this long value, long min, long max)
        {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }

        /// <summary>
        /// 获取数值的绝对值。
        /// </summary>
        /// <param name="value">要处理的数值。</param>
        /// <returns>绝对值。</returns>
        /// <example>
        /// <code>
        /// long negative = -100;
        /// long positive = negative.Abs(); // 返回 100
        /// </code>
        /// </example>
        public static long Abs(this long value) => Math.Abs(value);

        /// <summary>
        /// 返回当前值和另一个值中的较大值。
        /// </summary>
        /// <param name="value">当前值。</param>
        /// <param name="other">比较值。</param>
        /// <returns>两者中的较大值。</returns>
        /// <example>
        /// <code>
        /// long score = 85;
        /// long minScore = score.Max(60); // 返回 85
        /// </code>
        /// </example>
        public static long Max(this long value, long other) => Math.Max(value, other);

        /// <summary>
        /// 返回当前值和另一个值中的较小值。
        /// </summary>
        /// <param name="value">当前值。</param>
        /// <param name="other">比较值。</param>
        /// <returns>两者中的较小值。</returns>
        /// <example>
        /// <code>
        /// long remaining = 1000;
        /// long pageSize = remaining.Min(100); // 最多取100条
        /// </code>
        /// </example>
        public static long Min(this long value, long other) => Math.Min(value, other);

        /// <summary>
        /// 将数值向上取整到指定倍数。
        /// </summary>
        /// <param name="value">要处理的数值。</param>
        /// <param name="multiple">倍数（必须大于0）。</param>
        /// <returns>向上取整后的值。</returns>
        /// <exception cref="ArgumentException">当倍数小于等于0时抛出。</exception>
        /// <example>
        /// <code>
        /// long size = 1234;
        /// long rounded = size.RoundUpToMultiple(100); // 返回 1300
        /// 
        /// // 内存对齐
        /// long memSize = 1050;
        /// long aligned = memSize.RoundUpToMultiple(1024); // 对齐到1024字节
        /// </code>
        /// </example>
        public static long RoundUpToMultiple(this long value, long multiple)
        {
            if (multiple <= 0) throw new ArgumentException("倍数必须大于0", nameof(multiple));

            return ((value + multiple - 1) / multiple) * multiple;
        }

        /// <summary>
        /// 将数值向下取整到指定倍数。
        /// </summary>
        /// <param name="value">要处理的数值。</param>
        /// <param name="multiple">倍数（必须大于0）。</param>
        /// <returns>向下取整后的值。</returns>
        /// <exception cref="ArgumentException">当倍数小于等于0时抛出。</exception>
        /// <example>
        /// <code>
        /// long size = 1234;
        /// long rounded = size.RoundDownToMultiple(100); // 返回 1200
        /// </code>
        /// </example>
        public static long RoundDownToMultiple(this long value, long multiple)
        {
            if (multiple <= 0) throw new ArgumentException("倍数必须大于0", nameof(multiple));

            return (value / multiple) * multiple;
        }

        /// <summary>
        /// 将数值按比例缩放。
        /// </summary>
        /// <param name="value">原始值。</param>
        /// <param name="fromMin">原始范围最小值。</param>
        /// <param name="fromMax">原始范围最大值。</param>
        /// <param name="toMin">目标范围最小值。</param>
        /// <param name="toMax">目标范围最大值。</param>
        /// <returns>缩放后的值。</returns>
        /// <example>
        /// <code>
        /// // 将0-100的分数转换为0-5星级
        /// long score = 85;
        /// long stars = score.Scale(0, 100, 0, 5); // 返回 4
        /// 
        /// // 将传感器读数(0-1023)转换为百分比(0-100)
        /// long sensorValue = 512;
        /// long percentage = sensorValue.Scale(0, 1023, 0, 100);
        /// </code>
        /// </example>
        public static long Scale(this long value, long fromMin, long fromMax, long toMin, long toMax)
        {
            return (value - fromMin) * (toMax - toMin) / (fromMax - fromMin) + toMin;
        }

        #endregion

        #region 实用工具方法

        /// <summary>
        /// 计算数值的位数（不包括负号）。
        /// </summary>
        /// <param name="value">要计算的数值。</param>
        /// <returns>位数。</returns>
        /// <example>
        /// <code>
        /// long number = 12345;
        /// int digits = number.DigitCount(); // 返回 5
        /// 
        /// long negative = -9999;
        /// int digits2 = negative.DigitCount(); // 返回 4
        /// </code>
        /// </example>
        public static int DigitCount(this long value)
        {
            if (value == 0) return 1;
            return (int)Math.Floor(Math.Log10(Math.Abs(value))) + 1;
        }

        /// <summary>
        /// 执行指定次数的操作。
        /// </summary>
        /// <param name="count">执行次数。</param>
        /// <param name="action">要执行的操作，参数为当前索引（从0开始）。</param>
        /// <exception cref="ArgumentNullException">当action为null时抛出。</exception>
        /// <example>
        /// <code>
        /// // 打印10次
        /// 10L.Times(i => Console.WriteLine($"第{i + 1}次"));
        /// 
        /// // 批量创建数据
        /// var users = new List&lt;User&gt;();
        /// 100L.Times(i => users.Add(new User { Id = i, Name = $"User{i}" }));
        /// </code>
        /// </example>
        /// <remarks>
        /// 灵感来源于Ruby语言的times方法，使循环代码更简洁。
        /// </remarks>
        public static void Times(this long count, Action<long> action)
        {
            ArgumentNullException.ThrowIfNull(action);

            for (long i = 0; i < count; i++)
            {
                action(i);
            }
        }

        /// <summary>
        /// 生成从当前值到目标值的数字序列（包含边界）。
        /// </summary>
        /// <param name="start">起始值。</param>
        /// <param name="end">结束值。</param>
        /// <returns>数字序列。</returns>
        /// <example>
        /// <code>
        /// // 生成1到10的序列
        /// var numbers = 1L.To(10);
        /// foreach (var n in numbers)
        /// {
        ///     Console.WriteLine(n);
        /// }
        /// 
        /// // 倒序也支持
        /// var reverse = 10L.To(1); // 10, 9, 8, ..., 1
        /// 
        /// // LINQ结合使用
        /// var evenNumbers = 1L.To(100).Where(n => n.IsEven());
        /// </code>
        /// </example>
        public static IEnumerable<long> To(this long start, long end)
        {
            if (start <= end)
            {
                for (long i = start; i <= end; i++)
                    yield return i;
            }
            else
            {
                for (long i = start; i >= end; i--)
                    yield return i;
            }
        }

        #endregion
    }
}
